import { CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
import { onlyKey } from "@/utils/utilityFunction";
import gsap from 'gsap'
import { h, createApp } from "vue";
import { ElIcon } from "element-plus";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";

export default class Labels {
  constructor(viewer) {
    this.viewer = viewer
    this.scene = viewer.scene
    this.labelList = []
  }

  /**
   * 添加3d标签
   * @param {*} position
   * @param {*} html html内容
   */
  addCss3dLabel([x, y, z], iconName, input = "") {
    const tagvMode = createApp({
      render() {
        return h('div', [
          h('div', { class: 'element-tag' }, h('span', { class: 'tag-txt' }, input)),
          h('div', { class: 'tag-icon' }, h(ElIcon, h(ElementPlusIconsVue[iconName])))
        ]);
      },
    });

    let div = document.createElement('div')
    const backgroundColor = 'rgba(0,127,127,' + (Math.random() * 0.5 + 0.25) + ')'
    div.style.position = 'absolute'
    div.style.pointerEvents = 'none'
    const vNode = tagvMode.mount(document.createElement('div'))
    div.appendChild(vNode.$el)
    let label = new CSS3DObject(div)
    label.scale.set(0.15, 0.15, 0.15);//根据相机渲染范围控制HTML 3D标签尺寸
    label.position.set(x, y, z)
    label.element.style.pointerEvents = 'none'

    this.scene.add(label)

    const { uuid, position, element: { innerHTML, innerText } } = label
    const tag = {
      uuid,
      positionX: position.x,
      positionY: position.y,
      positionZ: position.z,
      innerText,
      innerHTML,
      width: 120,
      height: 80,
      fontSize: 14,
      backgroundColor,
      color: '#ffffffbf',
      iconColor: '#fff',
      iconSize: 12,
      iconName,
      hover: false
    }
    this.labelList.push(tag)

    return tag
  }

  deleteLabel(uuid) {
    const object = this.viewer.scene.getObjectByProperty('uuid', uuid)
    this.scene.remove(object)
    var element = object.element;
    if (element && element.parentNode) {
      element.parentNode.removeChild(element);
    }

    this.labelList = this.labelList.filter(v => v.uuid != uuid)
  }

  updateLabelElement(tag) {
    const object = this.scene.getObjectByProperty('uuid', tag.uuid)
    if (object) {
      const element = object.element.querySelector('.element-tag')
      const iconElement = object.element.querySelector('.tag-icon')
      const txtElement = object.element.querySelector('.tag-txt')
      const { height, backgroundColor, width,
        fontSize, color, innerText, iconColor,
        iconSize, positionY, positionX, positionZ } = tag

      element.style.height = height + 'px'
      element.style.backgroundColor = backgroundColor
      element.style.boxShadow = `0px 0px 4px ${backgroundColor}`
      element.style.width = width + 'px'
      element.style.fontSize = fontSize + 'px'
      element.style.color = color

      txtElement.innerText = innerText

      iconElement.style.fontSize = iconSize + 'px'
      iconElement.style.color = iconColor

      // 修改坐标位置
      gsap.to(object.position, {
        duration: 0.02,
        x: positionX,
        y: positionY,
        z: positionZ,
        ease: 'power1.inOut'
      })

      // 更新拖拽列表标签数据
      const activeTag = this.labelList.find(v => v.uuid == tag.uuid)
      Object.assign(activeTag, tag)
    }
  }

  clearSceneLabelss() {
    if (this.labelList.length == 0) return false
    this.labelList.forEach((v) => {
      const object = this.scene.getObjectByProperty('uuid', v.uuid)
      this.scene.remove(object)
      var element = object.element;
      if (element && element.parentNode) {
        element.parentNode.removeChild(element);
      }
    })
    this.labelList = []
  }

  hide(visible) {
    this.labelList.forEach((v) => {
      const object = this.scene.getObjectByProperty('uuid', v.uuid)
      object.visible = visible
    })
  }
}